﻿using AutoMapper;
using JTTD.DataBase;
using JTTD.DataBase.Model.UserInfo;
using JTTD.Domain.Dtos;
using JTTD.Domain.Dtos.UserInfo;
using JTTD.Domain.Dtos.UserInfo.Response;
using JTTD.Domain.IService;
using JTTD.Domain.Units;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using JTTD.Domain.Dtos.Account.Request;
using JTTD.Domain.Dtos.Account.Response;
using JTTD.Domain.Dtos.UserInfo.Request;
using JTTD.Common.Enum;
using JTTD.DataBase.Model.CompanyUserInfo;
using JTTD.Domain.Dtos.CompanyUserInfo.Response;
using JTTD.Common.Helper;

namespace JTTD.Domain.Service
{
    /// <summary>
    /// 用户信息服务
    /// </summary>
    public class UserInfoService : IUserInfoService
    {
        private readonly JTTDContext _context;
        private readonly IMapper _mapper;
        private readonly IIntegralService _integralService;

        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <param name="mapper"></param>
        /// <param name="integralService"></param>
        public UserInfoService(JTTDContext context, IMapper mapper, IIntegralService integralService)
        {
            _context = context;
            _mapper = mapper;
            _integralService = integralService;
        }

        /// <summary>
        /// 查询单个用户
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ApiResult<UserInfoResponseDto>> SearchUserInfo(SearchUserInfoRequestDto model)
        {
            try
            {
                UserInfoModel user = new UserInfoModel();
                if (model.Id > 0)
                    user = await _context.UserInfos.FirstOrDefaultAsync(x => x.Id == model.Id);

                if (!string.IsNullOrEmpty(model.Phone))
                    user = await _context.UserInfos.FirstOrDefaultAsync(x =>
                        x.Phone == model.Phone);

                if (!string.IsNullOrEmpty(model.WxOpenId))
                    user = await _context.UserInfos.FirstOrDefaultAsync(x =>
                        x.WxOpenId == model.WxOpenId);

                if (!string.IsNullOrEmpty(model.UserNumber))
                    user = await _context.UserInfos.FirstOrDefaultAsync(x =>
                        x.UserNumber == model.UserNumber);

                if (user == null || user.Id <= 0)
                    return ApiResultUnit.Error<UserInfoResponseDto>("查询用户失败");

                var info = new UserInfoResponseDto();
                info.Id = user.Id;
                info.Integral = await _integralService.GetUserIntegral(user.Id); //user.Integral;
                info.registerDate = user.RegisterDate;
                info.WxOpenId = user.WxOpenId;
                info.UserNumber = user.UserNumber;
                info.UserName = user.UserName;
                info.Phone = user.Phone;
                info.Gender = user.Gender;
                info.Birthday = user.Birthday;
                info.Email = user.Email;
                info.HeadUrl = user.HeadUrl;
                if (string.IsNullOrEmpty(info.Phone) || !info.Birthday.HasValue)
                    info.isComplete = false;
                else
                    info.isComplete = true;

                return ApiResultUnit.Success(info);
            }
            catch (Exception ex)
            {
                StringHelper.AddLgoToTXT(ex.ToString());
                return ApiResultUnit.Error<UserInfoResponseDto>(ex);
            }
        }

        /// <summary>
        /// 分页查询用户信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<ApiResult<PageResult<UserInfoResponseDto>>> SearchUserInfoPage(
            SearchUserInfoPageRequestDto request)
        {
            try
            {
                var query = _context.UserInfos.Where(x => true);
                if (!string.IsNullOrEmpty(request.Phone))
                {
                    query = query.Where(x => x.Phone == request.Phone.Trim());
                }

                if (!string.IsNullOrEmpty(request.UserNumber))
                {
                    query = query.Where(x => x.UserNumber == request.UserNumber.Trim());
                }

                if (!string.IsNullOrWhiteSpace(request.UserName))
                {
                    query = query.Where(x => x.UserName == request.UserName.Trim());
                }

                int count = await query.CountAsync();
                if (count > 0)
                {
                    var list = await query.OrderByDescending(item => item.RegisterDate)
                        .Skip((request.PageIndex - 1) * request.PageSize).Take(request.PageSize).ToListAsync();
                    var userIds = list.Select(item => item.Id).Distinct().ToArray();
                    var couponNumbers = await _context.CouponInfoModels.Where(item =>
                            userIds.Contains(item.UserId) && !item.IsUse && item.EndTime > DateTime.Now)
                        .GroupBy(item => item.UserId)
                        .Select(item => new { UserId = item.Key, CouponNumber = item.Count() }).ToListAsync();
                    var tempList = _mapper.Map<List<UserInfoResponseDto>>(list);
                    tempList.ForEach(item =>
                    {
                        item.CouponNumber =
                            couponNumbers.FirstOrDefault(args => args.UserId == item.Id)?.CouponNumber ?? 0;
                        item.Integral = _integralService.GetUserIntegral(item.Id).Result;
                    });
                    return new ApiResult<PageResult<UserInfoResponseDto>>()
                    {
                        IsSuccess = true,
                        Data = new PageResult<UserInfoResponseDto>
                        {
                            Data = tempList,
                            PageIndex = request.PageIndex,
                            PageSize = request.PageSize,
                            TotalNum = count,
                            TotalPageNum = (count % request.PageSize) == 0
                                ? count / request.PageSize
                                : count / request.PageSize + 1
                        }
                    };
                }
                else
                {
                    return new ApiResult<PageResult<UserInfoResponseDto>>()
                    {
                        Data = new PageResult<UserInfoResponseDto>()
                        {
                            PageIndex = request.PageIndex,
                            PageSize = request.PageSize,
                            Data = new List<UserInfoResponseDto>()
                        },
                        IsSuccess = true,
                        Message = "查询成功，暂无数据"
                    };
                }
            }
            catch (Exception ex)
            {
                StringHelper.AddLgoToTXT(ex.ToString());
                return new ApiResult<PageResult<UserInfoResponseDto>>()
                {
                    IsSuccess = false,
                    Message = "查询失败，" + ex.Message
                };
            }
        }

        /// <summary>
        /// 修改用户信息
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ApiResult<bool>> UpdateUser(int userId, UpdateUserRequestDto model)
        {
            try
            {
                var item = _context.UserInfos.Find(userId);
                if (item == null || item.Id <= 0)
                    return ApiResultUnit.Error<bool>("查询用户失败");

                if (string.IsNullOrEmpty(model.Phone))
                    return ApiResultUnit.Error<bool>("手机号码不能为空");

                if (!string.IsNullOrEmpty(model.Email))
                    item.Email = model.Email;

                if (model.Birthday.HasValue && !item.Birthday.HasValue)
                    item.Birthday = model.Birthday.Value;

                item.Phone = model.Phone;
                _context.UserInfos.Update(item);
                await _context.SaveChangesAsync();
                return ApiResultUnit.Success<bool>();
            }
            catch (Exception ex)
            {
                StringHelper.AddLgoToTXT(ex.ToString());
                return ApiResultUnit.Error<bool>(ex);
            }
        }

        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<ApiResult<int>> UserRegister(UserRegisterRequestDto dto)
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(dto.WxOpenId))
                {
                    var model = _context.UserInfos.FirstOrDefault(x => x.WxOpenId == dto.WxOpenId);
                    if (model != null && model.Id > 0)
                    {
                        return ApiResultUnit.Error<int>("该微信号已注册");
                    }
                }

                if (!string.IsNullOrWhiteSpace(dto.Phone))
                {
                    var model = _context.UserInfos.FirstOrDefault(item => item.Phone == dto.Phone.Trim());
                    if (model != null && model.Id > 0)
                    {
                        return ApiResultUnit.Error<int>("该手机号已注册");
                    }
                }

                var data = new UserInfoModel
                {
                    UserName = dto.UserName,
                    WxOpenId = dto.WxOpenId,
                    Gender = dto.Gender,
                    Birthday = dto.Birthday,
                    Phone = dto.Phone,
                    Email = dto.Email,
                    RegisterDate = DateTime.Now,
                    Integral = 0.0m,
                    HeadUrl = dto.HeadUrl
                };
                var user = _context.UserInfos.AddAsync(data);
                await _context.UserInfos.AddAsync(data);
                await _context.SaveChangesAsync();
                return ApiResultUnit.Success(data.Id);
            }
            catch (Exception ex)
            {
                StringHelper.AddLgoToTXT(ex.ToString());
                return ApiResultUnit.Error<int>(ex);
            }
        }

        /// <summary>
        /// 用户验证
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<ApiResult<AccountResponseDto>> UserAccount(AccountRequestDto request)
        {
            var result = new ApiResult<AccountResponseDto>
            { IsSuccess = false, Message = "登录失败，用户名或账号密码错误", Data = new AccountResponseDto() };
            try
            {
                if (request.UserType == UserTypeEnum.Ordinary)
                {
                    UserInfoModel user = null;
                    if (!string.IsNullOrWhiteSpace(request.OpenId))
                    {
                        user = await _context.UserInfos.FirstOrDefaultAsync(item =>
                            item.WxOpenId == request.OpenId.Trim());
                    }

                    //else if (!string.IsNullOrWhiteSpace(request.Phone) && !string.IsNullOrWhiteSpace(request.Password))
                    //{
                    //    user = await _context.UserInfos.FirstOrDefaultAsync(item => item.Phone == request.Phone.Trim() && item.Password == request.Password.Trim());
                    //}
                    if (user != null)
                    {
                        result.IsSuccess = true;
                        result.Message = "登录成功";
                        result.Data = new AccountResponseDto
                        {
                            UserId = user.Id,
                            UserName = user.UserName,
                            Phone = user.Phone,
                            UserType = (int)UserTypeEnum.Ordinary
                        };
                        return result;
                    }
                }

                if (request.UserType == UserTypeEnum.Shop)
                {
                    CompanyUserInfoModel user = null;
                    if (!string.IsNullOrWhiteSpace(request.OpenId))
                    {
                        user = await _context.CompanyUserInfoModels.FirstOrDefaultAsync(item =>
                            item.OpenId == request.OpenId.Trim() && item.UserType == UserTypeEnum.Shop);
                    }
                    else if (!string.IsNullOrWhiteSpace(request.Phone) && !string.IsNullOrWhiteSpace(request.Password))
                    {
                        user = await _context.CompanyUserInfoModels.FirstOrDefaultAsync(item =>
                            item.Phone == request.Phone.Trim() && item.Password == request.Password.Trim() &&
                            item.UserType == UserTypeEnum.Shop);
                    }

                    //else
                    //{
                    //    user = await _context.CompanyUserInfoModels.FirstOrDefaultAsync(item=>item.UserName==request.UserName.Trim()&&item.Password==request.Password.Trim());
                    //}
                    if (user != null)
                    {
                        if (user.AuditStatus != AuditStatusEnum.AuditPass)
                        {
                            return new ApiResult<AccountResponseDto>
                            { IsSuccess = false, Message = "抱歉，你申请入驻的店家账号暂未审核通过，请耐心等待" };
                        }

                        result.IsSuccess = true;
                        result.Message = "登录成功";
                        result.Data = new AccountResponseDto
                        {
                            UserId = user.Id,
                            UserName = user.UserName,
                            Phone = user.Phone,
                            UserType = (int)UserTypeEnum.Shop
                        };
                        return result;
                    }
                }

                if (request.UserType == UserTypeEnum.Admin)
                {
                    var user = await _context.CompanyUserInfoModels.FirstOrDefaultAsync(item =>
                        item.UserName == request.UserName.Trim() && item.Password == request.Password.Trim() &&
                        item.UserType == UserTypeEnum.Admin);
                    if (user != null)
                    {
                        result.IsSuccess = true;
                        result.Message = "登录成功";
                        result.Data = new AccountResponseDto
                        {
                            UserId = user.Id,
                            UserName = user.UserName,
                            Phone = user.Phone,
                            UserType = (int)UserTypeEnum.Admin
                        };
                        return result;
                    }
                }

                return result;
            }
            catch (Exception ex)
            {
                StringHelper.AddLgoToTXT(ex.ToString());
                return new ApiResult<AccountResponseDto>
                { IsSuccess = false, Message = "系统异常，" + ex.Message, Data = new AccountResponseDto() };
            }
        }

        /// <summary>
        /// 手机号注册
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ApiResult<int>> UserRegisterByPhone(UserRegisterRequestDto model)
        {
            try
            {
                if (string.IsNullOrEmpty(model.Phone) || string.IsNullOrEmpty(model.Password))
                    return ApiResultUnit.Error<int>("参数不能为空");

                var item = _context.UserInfos.FirstOrDefault(x => x.Phone == model.Phone);
                if (item != null && item.Id > 0)
                {
                    return ApiResultUnit.Error<int>("手机号码已注册");
                }

                var data = new UserInfoModel();
                data.UserName = model.UserName;
                data.Gender = model.Gender;
                data.Birthday = model.Birthday;
                data.Phone = model.Phone;
                data.Email = model.Email;
                data.RegisterDate = DateTime.Now;
                data.Integral = 0.0m;
                data.HeadUrl = model.HeadUrl;
                await _context.UserInfos.AddAsync(data);
                await _context.SaveChangesAsync();
                return ApiResultUnit.Success(data.Id);
            }
            catch (Exception ex)
            {
                StringHelper.AddLgoToTXT(ex.ToString());
                return ApiResultUnit.Error<int>(ex);
            }
        }

        /// <summary>
        /// 重置用户密码
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        //public async Task<ApiResult<bool>> ResetUserPassword(int userId)
        //{
        //    try
        //    {
        //        var data = await _context.UserInfos.FirstOrDefaultAsync(x => x.Id == userId);
        //        if (data != null)
        //        {
        //            data.Password = "000000";
        //            _context.Update(data);
        //            var result = await _context.SaveChangesAsync();
        //            return ApiResultUnit.Success(result > 0);
        //        }
        //        else
        //        {
        //            return ApiResultUnit.Error<bool>("用户不存在");
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return ApiResultUnit.Error<bool>(ex);
        //    }
        //}

        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="dto"></param>
        /// <returns></returns>
        //public async Task<ApiResult<bool>> ModifyUserPassword(int userId, UpdateUserPwdRequestDto dto)
        //{
        //    try
        //    {
        //        var data = await _context.UserInfos.FindAsync(userId);
        //        if (data != null)
        //        {
        //            if (dto.OldPwd != data.Password)
        //            {
        //                return new ApiResult<bool> { IsSuccess = false, Message = "旧密码错误" };
        //            }
        //            data.Password = dto.NewPwd;
        //            _context.Update(data);
        //            var result = await _context.SaveChangesAsync();
        //            return ApiResultUnit.Success(result > 0);
        //        }
        //        else
        //        {
        //            return ApiResultUnit.Error<bool>("用户不存在");
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return ApiResultUnit.Error<bool>(ex);
        //    }
        //}

        /// <summary>
        /// 用户关注店家
        /// </summary>
        /// <param name="shopId"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<ApiResult<bool>> AttentionShop(int shopId, int userId)
        {
            try
            {
                var user = await _context.UserInfos.FirstOrDefaultAsync(x => x.Id == userId);
                if (user == null)
                {
                    return ApiResultUnit.Error<bool>("用户不存在");
                }

                var shop = await _context.CompanyUserInfoModels.FirstOrDefaultAsync(x => x.Id == shopId);
                if (shop == null)
                {
                    return ApiResultUnit.Error<bool>("店铺不存在");
                }

                var data = new UserShopRelationModel
                {
                    CompanyUserId = shopId,
                    UserId = userId
                };
                await _context.UserShopRelationModels.AddAsync(data);
                var result = await _context.SaveChangesAsync();
                return ApiResultUnit.Success(result > 0);
            }
            catch (Exception ex)
            {
                StringHelper.AddLgoToTXT(ex.ToString());
                return ApiResultUnit.Error<bool>(ex);
            }
        }

        /// <summary>
        /// 用户取消关注店家
        /// </summary>
        /// <param name="shopId"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<ApiResult<bool>> CancelAttentionShop(int shopId, int userId)
        {
            try
            {
                var user = await _context.UserInfos.FirstOrDefaultAsync(x => x.Id == userId);
                if (user == null)
                {
                    return ApiResultUnit.Error<bool>("用户不存在");
                }

                var shop = await _context.CompanyUserInfoModels.FirstOrDefaultAsync(x => x.Id == shopId);
                if (shop == null)
                {
                    return ApiResultUnit.Error<bool>("店铺不存在");
                }

                var data = await _context.UserShopRelationModels.FirstOrDefaultAsync(x =>
                    x.UserId == userId && x.CompanyUserId == shopId);
                _context.UserShopRelationModels.Remove(data);
                var result = await _context.SaveChangesAsync();
                return ApiResultUnit.Success(result > 0);
            }
            catch (Exception ex)
            {
                StringHelper.AddLgoToTXT(ex.ToString());
                return ApiResultUnit.Error<bool>(ex);
            }
        }

        /// <summary>
        /// 用户查询自己关注的店家
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="search"></param>
        /// <returns></returns>
        public async Task<ApiResult<PageResult<GetShopUserDto>>> GetUserAttentionShops(int userId, BaseSearch search)
        {
            var query = _context.UserShopRelationModels.Where(item => item.UserId == userId);
            int count = await query.CountAsync();
            if (count > 0)
            {
                var list = await query.Skip((search.PageIndex - 1) * search.PageSize).Take(search.PageSize)
                    .ToListAsync();
                var shopIds = list.Select(item => item.CompanyUserId).ToArray();
                var shopList = await _context.CompanyUserInfoModels.Where(item =>
                    item.UserType == UserTypeEnum.Shop && item.AuditStatus == AuditStatusEnum.AuditPass &&
                    shopIds.Contains(item.Id)).ToListAsync();
                int total = shopList.Count;
                return new ApiResult<PageResult<GetShopUserDto>>()
                {
                    IsSuccess = true,
                    Data = new PageResult<GetShopUserDto>
                    {
                        Data = _mapper.Map<List<GetShopUserDto>>(shopList),
                        PageIndex = search.PageIndex,
                        PageSize = search.PageSize,
                        TotalNum = total,
                        TotalPageNum = (total % search.PageSize) == 0
                            ? total / search.PageSize
                            : total / search.PageSize + 1
                    }
                };
            }
            else
            {
                return new ApiResult<PageResult<GetShopUserDto>>()
                {
                    Data = new PageResult<GetShopUserDto>()
                    {
                        PageIndex = search.PageIndex,
                        PageSize = search.PageSize,
                        Data = new List<GetShopUserDto>()
                    },
                    IsSuccess = true,
                    Message = "查询成功，暂无数据"
                };
            }
        }

        /// <summary>
        /// 检查用户信息是否完善
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<ApiResult<bool>> CheckUserInfo(int userId)
        {
            var user = await _context.UserInfos.FirstOrDefaultAsync(x => x.Id == userId);
            if (user == null)
            {
                return ApiResultUnit.Error<bool>("用户不存在");
            }

            if (string.IsNullOrEmpty(user.Phone) || !user.Birthday.HasValue)
                return ApiResultUnit.Error<bool>("用户信息不全");
            else
                return ApiResultUnit.Success(true);
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<ApiResult<bool>> DeleteUserInfo(int userId)
        {
            try
            {
                var user = await _context.UserInfos.FirstOrDefaultAsync(x => x.Id == userId);
                if (user == null)
                {
                    return ApiResultUnit.Error<bool>("用户不存在");
                }

                _context.UserInfos.Remove(user);
                await _context.SaveChangesAsync();
                return ApiResultUnit.Success(true);
            }
            catch (Exception ex)
            {
                StringHelper.AddLgoToTXT(ex.ToString());
                return ApiResultUnit.Error<bool>(ex.ToString());
            }
        }
    }
}